package org.commonsemantics.scigrails.module.users

import grails.converters.JSON 
import grails.plugins.springsecurity.Secured 
import org.commonsemantics.scigrails.module.users.circle.UserCircle 
import org.commonsemantics.scigrails.module.users.community.UserCommunity 
import org.commonsemantics.scigrails.module.users.group.DefaultGroupRoles 
import org.commonsemantics.scigrails.module.users.group.DefaultGroupStatus 
import org.commonsemantics.scigrails.module.users.group.Group 
import org.commonsemantics.scigrails.module.users.group.GroupRole 
import org.commonsemantics.scigrails.module.users.group.GroupStatus 
import org.commonsemantics.scigrails.module.users.group.UserGroup 
import org.commonsemantics.scigrails.module.users.security.Role 
import org.commonsemantics.scigrails.module.users.security.DefaultRoles 
import org.commonsemantics.scigrails.module.users.security.User 
import org.commonsemantics.scigrails.module.users.security.UserRole 

/**
* @author Paolo Ciccarese <paolo.ciccarese@gmail.com>
*/
class UsersController {
	
	def springSecurityService
	
	private def injectUserProfile() {
		def principal = springSecurityService.principal
		String username = principal.username
		def user = User.findByUsername(username);
		//def person = AgentPerson.findByEmail(user.email)
		//session['loggedPerson'] = person
		user
	}
	
	
	def index = {
		render 'Users Module Index Page'
	}
	
	//  GROUPS
	// --------
	/**
	 * Sends to the view for creating a new group
	 */
	@Secured(['ROLE_ADMIN'])
	def createGroup = {
		render (view:'createGroup',  model:[action: "create"]);
	}
	@Secured(['ROLE_ADMIN'])
	def showGroup = {
		def group = Group.findById(params.id)
		render (view:'showGroup', model:[item: group]);
	}
	/**
	 * It tries to save the requested group. If the validation is not successful
	 * it sends the control back - with errors - to the view for creating a group
	 */
	@Secured(['ROLE_ADMIN'])
	def saveGroup = { GroupCreateCommand groupCreateCmd ->
		if(groupCreateCmd.hasErrors()) {
			/* groupCreateCmd.errors.allErrors.each { println it } */
			render(view:'createGroup', model:[item:groupCreateCmd])
		} else {
			def group = groupCreateCmd.createGroup()
			if(group)  {
				if(!group.save()) {
					// Failure in saving
					group.errors.allErrors.each { println it }
					render(view:'createGroup', model:[item:groupCreateCmd,
						msgError: 'The group has not been saved successfully'])
				} else {
					println group.id
					redirect (action:'showGroup',id: group.id, model: [
						msgSuccess: 'Group saved successfully']);
				}
			} else {
				// Group already existing
				render(view:'createGroup', model:[item:groupCreateCmd, 
					msgError: 'A group with this name is already existing'])
			}
		}
	}
	@Secured(['ROLE_ADMIN'])
	def editGroup = {
		def group = Group.findById(params.id)
		render (view:'editGroup', model:[item: group, action: "edit"]);
	}
	@Secured(['ROLE_ADMIN'])
	def updateGroup = { GroupCreateCommand groupCreateCmd ->
		if(groupCreateCmd.hasErrors()) {
			/* groupCreateCmd.errors.allErrors.each { println it } */
			render(view:'editGroup', model:[item:groupCreateCmd])
		} else {
			def group = Group.findById(params.id)
			group.name = groupCreateCmd.name
			group.shortName = groupCreateCmd.shortName
			group.description = groupCreateCmd.description
			println groupCreateCmd.status
			if(groupCreateCmd.status.equals(GroupStatus.ACTIVE_GROUP.value())) {
				group.enabled = true
				group.locked = false
			} else if(groupCreateCmd.status.equals(GroupStatus.DISABLED_GROUP.value())) {
				group.enabled = false
				group.locked = false
			} else if(groupCreateCmd.status.equals(GroupStatus.LOCKED_GROUP.value())) {
				group.enabled = true
				group.locked = true
			} 
			
			render (view:'showGroup', model:[item: group]);
		}
	}
	@Secured(['ROLE_ADMIN'])
	def deleteGroup = { GroupCreateCommand groupCreateCmd ->
		def group = Group.findById(params.id)
		group.delete();
		redirect (action:'listGroups');
	}
	@Secured(['ROLE_ADMIN'])
	def listGroups = {
		if (!params.max) params.max = 15
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "groupsCount"
		if (!params.order) params.order = "asc"
		

		
		def groups = [];
		def groupsCount = [:]
		Group.list().each { agroup ->
			groupsCount.put (agroup.id, UserGroup.findAllWhere(group: agroup).size())
		}
		def groupsStatus = [:]
		Group.list().each { agroup ->
			groupsStatus.put (agroup.id, agroup.status)
		}
		
		if (params.sort == 'groupsCount') {
			groupsCount = groupsCount.sort{ a, b -> a.value <=> b.value }
			if(params.order == "desc")
				groupsCount.each { groupCount ->
					groups.add Group.findById(groupCount.key);
				}
			else
				groupsCount.reverseEach { groupCount ->
					groups.add Group.findById(groupCount.key);
				}
		} else if (params.sort == 'status') {
			groupsStatus = groupsStatus.sort{ a, b -> a.value.compareTo(b.value) }
			if(params.order == "desc")
				groupsStatus.each { groupStatus ->
					groups.add Group.findById(groupStatus.key);
				}
			else
				groupsStatus.reverseEach { groupStatus ->
					groups.add Group.findById(groupStatus.key);
				}
		} else {
			groups = Group.withCriteria {
				maxResults(params.max?.toInteger())
				firstResult(params.offset?.toInteger())
				order(params.sort, params.order)
			}
		}
		
		render (view:'listGroups', model:["groups" : groups, "groupsTotal": Group.count(), "groupsCount": groupsCount, "menuitem" : "listGroups"])
	}
	
	@Secured(['ROLE_ADMIN'])
	def lockGroup = {
		def group = Group.findById(params.id)
		group.locked = true
		if(params.redirect)
			redirect(action:params.redirect)
		else
			render (view:'showGroup', model:[item: group]);
	}
	
	@Secured(['ROLE_ADMIN'])
	def unlockGroup = {
		def group = Group.findById(params.id)
		group.locked = false
		if(params.redirect)
			redirect(action:params.redirect)
		else
			render (view:'showGroup', model:[item: group]);
	}
	
	@Secured(['ROLE_ADMIN'])
	def enableGroup = {
		def group = Group.findById(params.id)
		group.enabled = true
		if(params.redirect)
			redirect(action:params.redirect)
		else
			render (view:'showGroup', model:[item: group]);
	}
	
	@Secured(['ROLE_ADMIN'])
	def disableGroup = {
		def group = Group.findById(params.id)
		group.enabled = false
		if(params.redirect)
			redirect(action:params.redirect)
		else
			render (view:'showGroup', model:[item: group]);
	}
	
	@Secured(['ROLE_ADMIN'])
	def assignUsersToGroups = {
		render (view:'assignUsersToGroups', model:[item: group]);
	}
	
	//  USERS 
	// --------
	def createUser = {
		render (view:'createUser',  model:[action: "create", roles: Role.list(), defaultRole: DefaultRoles.USER, "menuitem" : "createUser"]);
	}
	@Secured(['ROLE_ADMIN'])
	def saveUser = { UserCreateCommand userCreateCmd ->
		if(userCreateCmd.hasErrors()) {
			/* groupCreateCmd.errors.allErrors.each { println it } */
			render(view:'createUser', model:[item:userCreateCmd, roles: Role.list()])
		} else {
			def user = userCreateCmd.createUser()
			if(user)  {
				if(!user.save()) {
					// Failure in saving
					user.errors.allErrors.each { println it }
					render(view:'createUser', model:[item:userCreateCmd, roles: Role.list(),
						msgError: 'The user has not been saved successfully'])
				} else {
					updateUserRole(user, Role.findByAuthority(DefaultRoles.ADMIN.value()), params.Admin)
					updateUserRole(user, Role.findByAuthority(DefaultRoles.MANAGER.value()), params.Manager)
					updateUserRole(user, Role.findByAuthority(DefaultRoles.USER.value()), params.User)

					redirect (action:'showUser',id: user.id, model: [
						msgSuccess: 'Group saved successfully']);
				}
			} else {
				// User already existing
				render(view:'createUser', model:[item:userCreateCmd, roles: Role.list(),
					msgError: 'A user with this name is already existing'])
			}
		}
	}
	@Secured(['ROLE_ADMIN'])
	def showUser = {
		def user = User.findById(params.id)
		render (view:'showUser', model:[item: user, userRoles: getUserRoles(user), 
			userGroups: getUserGroups(user), userCircles: getUserCircles(user), userCommunities: getUserCommunities(user)]);
	}
	@Secured(['ROLE_ADMIN'])
	def editUser = {
		def user = User.findById(params.id)
		
		render (view:'editUser', model:[item: user, userRoles: getUserRoles(user), roles: Role.list(), userGroups: getUserGroups(user), action: "edit", 
			groupRoles: listOfGroupRoles(), groupStatus: listOfUserGroupStatus()]);
	}
	
	public def listOfGroupRoles() {
		def roles = []
		roles.add(DefaultGroupRoles.ADMIN)
		roles.add(DefaultGroupRoles.MANAGER)
		roles.add(DefaultGroupRoles.USER)
		roles
	}
	
	public def listOfUserGroupStatus() {
		def roles = []
		roles.add(DefaultGroupStatus.ACTIVE)
		roles.add(DefaultGroupStatus.SUSPENDED)
		roles.add(DefaultGroupStatus.DELETED)
		roles
	}
	
	@Secured(['ROLE_ADMIN'])
	def updateUser = { UserCreateCommand userCreateCmd ->
		if(userCreateCmd.hasErrors()) {
			/* groupCreateCmd.errors.allErrors.each { println it } */
			render(view:'editUser', model:[item:userCreateCmd])
		} else {
			def user = User.findById(params.id)
			user.firstName = userCreateCmd.firstName
			user.lastName = userCreateCmd.lastName
			user.displayName = userCreateCmd.displayName
			
			updateUserRole(user, Role.findByAuthority(DefaultRoles.ADMIN.value()), params.Admin)
			updateUserRole(user, Role.findByAuthority(DefaultRoles.MANAGER.value()), params.Manager)
			updateUserRole(user, Role.findByAuthority(DefaultRoles.USER.value()), params.User)
			
			render (view:'showUser', model:[item: user, userRoles: getUserRoles(user)]);
		}
		
	}
	
	def updateUserRole(def user, def role, def value) {
		if(value=='on') {
			UserRole ur = UserRole.create(user, role)
			ur.save(flush:true);
		} else {
			def ur = UserRole.findByUserAndRole(user, role);
			if(ur!=null) {
				ur.delete(flush:true);
			}
		}
	}
	
	def getUserRoles(def user) {
		def userRoles = []
		def ur = UserRole.findAllByUser(user)
		println ur
		ur.each { userRoles.add(it.role)}
		return userRoles;
	}
	
	def getUserGroups(def user) {
		def ur = []
		def userGroups = []
		ur = UserGroup.findAllByUser(user)
		ur.each { userGroups.add(it.group)}
		return ur;
	}
	
	def getUserCircles(def user) {
		def ur = []
		def userCircles = []
		ur = UserCircle.findAllByUser(user)
		ur.each { userCircles.add(it.circle)}
		return ur;
	}
	
	def getUserCommunities(def user) {
		def ur = []
		def userCommunities = []
		ur = UserCommunity.findAllByUser(user)
		ur.each { userCommunities.add(it.community)}
		return ur;
	}
	
	@Secured(['ROLE_ADMIN'])
	def listUsers = {
		def user = injectUserProfile()
		
		if (!params.max) params.max = 1
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "username"
		if (!params.order) params.order = "asc"

		//TODO fix pagination
		def users = [];
		if (params.sort == 'status') {
			def buffer = [];
			def usersStatus = [:]
			User.list().each { auser ->
				usersStatus.put (auser.id, auser.status)
			}
			usersStatus = usersStatus.sort{ a, b -> a.value.compareTo(b.value) }
			if(params.order == "desc")
				usersStatus.each { userStatus ->
					buffer.add(User.findById(userStatus.key));
				}
			else
				usersStatus.reverseEach { userStatus ->
					buffer.add(User.findById(userStatus.key));
				}
				
			int offset = (params.offset instanceof String) ? Integer.parseInt(params.offset) : params.offset
			int max = (params.max instanceof String) ? Integer.parseInt(params.max) : params.max
			for(int i=offset;i< Math.min(offset+max, usersStatus.size()); i++) {
				users.add(buffer[i]);
			}
		} else if (params.sort == 'isAdmin' || params.sort == 'isAnalyst' || params.sort == 'isManager'
			|| params.sort == 'isCurator' || params.sort == 'isUser') {
		
		} else if (params.sort == 'name') {
			def buffer = [];
			def usersNames = [:]
			User.list().each { auser ->
				usersNames.put (auser.id, auser.name)
			}
			usersNames = usersNames.sort{ a, b -> a.value.compareTo(b.value) }
			if(params.order == "desc")
				usersNames.each { userName ->
					buffer.add(User.findById(userName.key));
				}
			else
				usersNames.reverseEach { userName ->
					buffer.add(User.findById(userName.key));
				}
			int offset = (params.offset instanceof String) ? Integer.parseInt(params.offset) : params.offset
			int max = (params.max instanceof String) ? Integer.parseInt(params.max) : params.max
			for(int i=offset;i< Math.min(offset+max, usersNames.size()); i++) {
				users.add(buffer[i]);
			}
		} else {
			def userStatusCriteria = User.createCriteria();
			def r = userStatusCriteria.list {
				maxResults(params.max?.toInteger())
				firstResult(params.offset?.toInteger())
				order(params.sort, params.order)	
			}
			users = r.toList();
		}

		render (view:'listUsers', model:[user: user, "users" : users, "usersTotal": User.count(), "usersroles": UserRole.list(), "roles" : Role.list(), "menuitem" : "listUsers"])
	}
	
	@Secured(['ROLE_ADMIN'])
	def listRoleUsers = {
		def user = injectUserProfile()
		
		if (!params.max) params.max = 15
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "username"
		if (!params.order) params.order = "asc"

		//TODO fix pagination
		def users = [];
		if (params.sort == 'status') {
			def buffer = [];
			def usersStatus = [:]
			User.list().each { auser ->
				usersStatus.put (auser.id, auser.status)
			}
			usersStatus = usersStatus.sort{ a, b -> a.value.compareTo(b.value) }
			if(params.order == "desc")
				usersStatus.each { userStatus ->
					buffer.add(User.findById(userStatus.key));
				}
			else
				usersStatus.reverseEach { userStatus ->
					buffer.add(User.findById(userStatus.key));
				}
				
			int offset = (params.offset instanceof String) ? Integer.parseInt(params.offset) : params.offset
			int max = (params.max instanceof String) ? Integer.parseInt(params.max) : params.max
			for(int i=offset;i< Math.min(offset+max, usersStatus.size()); i++) {
				users.add(buffer[i]);
			}
		} else if (params.sort == 'isAdmin' || params.sort == 'isAnalyst' || params.sort == 'isManager'
			|| params.sort == 'isCurator' || params.sort == 'isUser') {
		
		} else if (params.sort == 'name') {
			def buffer = [];
			def usersNames = [:]
			User.list().each { auser ->
				usersNames.put (auser.id, auser.name)
			}
			usersNames = usersNames.sort{ a, b -> a.value.compareTo(b.value) }
			if(params.order == "desc")
				usersNames.each { userName ->
					buffer.add(User.findById(userName.key));
				}
			else
				usersNames.reverseEach { userName ->
					buffer.add(User.findById(userName.key));
				}
			int offset = (params.offset instanceof String) ? Integer.parseInt(params.offset) : params.offset
			int max = (params.max instanceof String) ? Integer.parseInt(params.max) : params.max
			for(int i=offset;i< Math.min(offset+max, usersNames.size()); i++) {
				users.add(buffer[i]);
			}
		} else {
			def userStatusCriteria = User.createCriteria();
			def r = userStatusCriteria.list {
				maxResults(params.max?.toInteger())
				firstResult(params.offset?.toInteger())
				order(params.sort, params.order)
			}
			users = r.toList();
		}
		
		def role = Role.findById(params.id)

		render (view:'listUsers', model:[user: user, "users" : users, "usersTotal": User.count(), "usersroles": UserRole.list(), "roles" : Role.list(), 
			"menuitem" : "listUsers", role: role])
	}
	
	//  ROLES
	// --------
	@Secured(['ROLE_ADMIN'])
	def listRoles = {
		def user = injectUserProfile()
		
		if (!params.max) params.max = 15
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "authority"
		if (!params.order) params.order = "asc"
		
		def rolesCount = [:]
		Role.list().each { arole ->
			rolesCount.put (arole.id, UserRole.findAllWhere(role: arole).size())
		}
		
		def roles = [];
		if (params.sort == 'rolesCount') {
			rolesCount.sort({ a, b -> a <=> b } as Comparator)
			if(params.order == "desc")
				rolesCount.each { roleCount ->
					roles.add Role.findById(roleCount.key);
				}
			else
				rolesCount.reverseEach { roleCount ->
					roles.add Role.findById(roleCount.key);
				}
		} else {
			roles = Role.withCriteria {
				maxResults(params.max?.toInteger())
				firstResult(params.offset?.toInteger())
				order(params.sort, params.order)
			}
		}
		
		render (view:'listRoles', model:[user : user, "roles" : roles, "rolesTotal": Role.count(), "rolesCount": rolesCount, "menuitem" : "listRoles"])
	}
	
	//  ROLES
	// --------
	@Secured(['ROLE_ADMIN'])
	def listGroupRoles = {
		def user = injectUserProfile()
		
		if (!params.max) params.max = 15
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "authority"
		if (!params.order) params.order = "asc"
		
		def rolesCount = [:]
		GroupRole.list().each { arole ->
			rolesCount.put (arole.id, UserGroup.findAllWhere(role: arole).size())
		}
		
		def roles = [];
		if (params.sort == 'rolesCount') {
			rolesCount.sort({ a, b -> a <=> b } as Comparator)
			if(params.order == "desc")
				rolesCount.each { roleCount ->
					roles.add GroupRole.findById(roleCount.key);
				}
			else
				rolesCount.reverseEach { roleCount ->
					roles.add GroupRole.findById(roleCount.key);
				}
		} else {
			roles = GroupRole.withCriteria {
				maxResults(params.max?.toInteger())
				firstResult(params.offset?.toInteger())
				order(params.sort, params.order)
			}
		}
		
		render (view:'listGroupRoles', model:[user : user, "roles" : roles, "rolesTotal": Role.count(), "rolesCount": rolesCount, "menuitem" : "listGroupRoles"])
	}
	
	def searchUserForm = {
		render (view:'searchUser', model:["menuitem" : "searchUser"]);
	}
	
	def searchUser = {
		def user = injectUserProfile()
		
		if (!params.max) params.max = 1
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "username"
		if (!params.order) params.order = "asc"

		//TODO fix pagination
		def users = [];
		if (params.sort == 'status') {
			def buffer = [];
			def usersStatus = [:]
			User.list().each { auser ->
				usersStatus.put (auser.id, auser.status)
			}
			usersStatus = usersStatus.sort{ a, b -> a.value.compareTo(b.value) }
			if(params.order == "desc")
				usersStatus.each { userStatus ->
					buffer.add(User.findById(userStatus.key));
				}
			else
				usersStatus.reverseEach { userStatus ->
					buffer.add(User.findById(userStatus.key));
				}
				
			int offset = (params.offset instanceof String) ? Integer.parseInt(params.offset) : params.offset
			int max = (params.max instanceof String) ? Integer.parseInt(params.max) : params.max
			for(int i=offset;i< Math.min(offset+max, usersStatus.size()); i++) {
				users.add(buffer[i]);
			}
		} else if (params.sort == 'isAdmin' || params.sort == 'isAnalyst' || params.sort == 'isManager'
			|| params.sort == 'isCurator' || params.sort == 'isUser') {
		
		} else if (params.sort == 'name') {
			def buffer = [];
			def usersNames = [:]
			User.list().each { auser ->
				usersNames.put (auser.id, auser.name)
			}
			usersNames = usersNames.sort{ a, b -> a.value.compareTo(b.value) }
			if(params.order == "desc")
				usersNames.each { userName ->
					buffer.add(User.findById(userName.key));
				}
			else
				usersNames.reverseEach { userName ->
					buffer.add(User.findById(userName.key));
				}
			int offset = (params.offset instanceof String) ? Integer.parseInt(params.offset) : params.offset
			int max = (params.max instanceof String) ? Integer.parseInt(params.max) : params.max
			for(int i=offset;i< Math.min(offset+max, usersNames.size()); i++) {
				users.add(buffer[i]);
			}
		} else {
			// Search with no ordering
			def userStatusCriteria = User.createCriteria();
			def r = [];
			if(params.firstName!=null && params.firstName.trim().length()>0 &&
				params.lastName!=null && params.lastName.trim().length()>0) {
				r = userStatusCriteria.list {
					maxResults(params.max?.toInteger())
					firstResult(params.offset?.toInteger())
					order(params.sort, params.order)
					and {
						like('firstName', params.firstName)
						like('lastName', params.lastName)
					}
				}
			} else if(params.firstName!=null && params.firstName.trim().length()>0 &&
				(params.lastName==null || params.lastName.trim().length()==0)) {
				r = userStatusCriteria.list {
					maxResults(params.max?.toInteger())
					firstResult(params.offset?.toInteger())
					order(params.sort, params.order)
					like('firstName', params.firstName)
				}
			} else if((params.firstName==null || params.firstName.trim().length()==0) &&
				params.lastName!=null &&  params.lastName.trim().length()>0) {
				r = userStatusCriteria.list {
					maxResults(params.max?.toInteger())
					firstResult(params.offset?.toInteger())
					order(params.sort, params.order)
					like('lastName', params.lastName)
				}
			} else if(params.displayName!=null && params.displayName.trim().length()>0) {
				r = userStatusCriteria.list {
					maxResults(params.max?.toInteger())
					firstResult(params.offset?.toInteger())
					order(params.sort, params.order)
					like('displayName', params.displayName)
				}
			}
			users = r.toList();
		}
		
		def usersResults = []
		users.each { userItem ->
			def userResult = [id:userItem.id, username:userItem.username, name: userItem.getName(),
				displayName: userItem.getDisplayName(),
				isAdmin: userItem.getIsAdmin(), isManager: userItem.getIsManager(), isUser: userItem.getIsUser(),
				status: userItem.getStatus(), dateCreated: userItem.dateCreated]
			usersResults << userResult
		}
		
		def paginationResults = ['offset':params.offset+params.max, 'sort':params.sort, 'order':params.order]
		
		
		def results = [users: usersResults, pagination: paginationResults]
		render results as JSON
	}
	
	def searchGroupForm = {
		render (view:'searchGroup', model:["menuitem" : "searchGroup"]);
	}
	
	def searchGroup = {
		def user = injectUserProfile()
		
		if (!params.max) params.max = 15
		if (!params.offset) params.offset = 0
		if (!params.sort) params.sort = "groupsCount"
		if (!params.order) params.order = "asc"
		
		def groups = [];
		def groupsCount = [:]
		Group.list().each { agroup ->
			groupsCount.put (agroup.id, UserGroup.findAllWhere(group: agroup).size())
		}
		def groupsStatus = [:]
		Group.list().each { agroup ->
			groupsStatus.put (agroup.id, agroup.status)
		}
		
		println params.sort
		
		if (params.sort == 'groupsCount') {
			groupsCount = groupsCount.sort{ a, b -> a.value <=> b.value }
			if(params.order == "desc")
				groupsCount.each { groupCount ->
					groups.add Group.findById(groupCount.key);
				}
			else
				groupsCount.reverseEach { groupCount ->
					groups.add Group.findById(groupCount.key);
				}
		} else if (params.sort == 'status') {
			groupsStatus = groupsStatus.sort{ a, b -> a.value.compareTo(b.value) }
			if(params.order == "desc")
				groupsStatus.each { groupStatus ->
					groups.add Group.findById(groupStatus.key);
				}
			else
				groupsStatus.reverseEach { groupStatus ->
					groups.add Group.findById(groupStatus.key);
				}
		} else {
			// Search with no ordering
			def groupCriteria = Group.createCriteria();
			def r = [];

			if(params.name!=null && params.name.trim().length()>0 &&
				params.nickname!=null && params.nickname.trim().length()>0) {
				r = groupCriteria.list {
					maxResults(params.max?.toInteger())
					firstResult(params.offset?.toInteger())
					order(params.sort, params.order)
					and {
						like('name', params.name)
						like('nickname', params.nickname)
					}
				}
			} else if(params.name!=null && params.name.trim().length()>0 &&
				(params.nickname==null || params.nickname.trim().length()==0)) {
				r = groupCriteria.list {
					maxResults(params.max?.toInteger())
					firstResult(params.offset?.toInteger())
					order(params.sort, params.order)
					like('name', params.name)
				}
			} else if((params.name==null || params.name.trim().length()==0) &&
				params.nickname!=null &&  params.nickname.trim().length()>0) {
				r = groupCriteria.list {
					maxResults(params.max?.toInteger())
					firstResult(params.offset?.toInteger())
					order(params.sort, params.order)
					like('nickname', params.nickname)
				}
			} else {
				r = groupCriteria.list {
					maxResults(params.max?.toInteger())
					firstResult(params.offset?.toInteger())
					order(params.sort, params.order)
				}
			}
			groups = r.toList();
		}
		
		
		def groupsResults = []
		groups.each { groupItem ->
			def groupResult = [id:groupItem.id, name:groupItem.name, nickname: groupItem.nickname,
				description: groupItem.description, status: groupItem.status, dateCreated: groupItem.dateCreated]
			groupsResults << groupResult
		}
		
		def paginationResults = ['offset':params.offset+params.max, 'sort':params.sort, 'order':params.order]
		
		
		def results = [groups: groupsResults, pagination: paginationResults, groupsCount: groupsCount]
		render results as JSON
	}
	
	// USER
	//-------------------------------------
	def manageCommunitiesOfUser = {
		def user = User.findById(params.id)
		render (view:'manageCommunitiesOfUser', model:["menuitem" : "manageCommunitiesOfUser",
			item: user, userCommunities: getUserCommunities(user)]);
	}
	
	def manageGroupsOfUser = {
		def user = User.findById(params.id)
		render (view:'manageGroupsOfUser', model:["menuitem" : "manageGroupsOfUser",
			item: user, userGroups: getUserGroups(user)]);
	}
	
	def manageCirclesOfUser = {
		def user = User.findById(params.id)
		render (view:'manageCirclesOfUser', model:["menuitem" : "manageCirclesOfUser",
			item: user, userCircles: getUserCircles(user)]);
	}
}
